package com.intelligentpension.fingerprintidentification

import android.app.KeyguardManager
import android.content.Context
import android.hardware.fingerprint.FingerprintManager
import android.os.Build
import android.preference.PreferenceManager
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
import androidx.annotation.RequiresApi
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricPrompt
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import com.hjq.toast.ToastUtils
import java.security.KeyStore
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey


/**
 * 版权：点赞 版权所有
 * author :赵航
 * @e-mail: zhaohangcn@gmail.com
 * time：2022/4/12
 * describe ：
 */
object FingerUtils {
    private const val DEFAULT_KEY_NAME = "default_key"

    /**
     *  10.0以上判断方法返回值见上文的“是否可用的状态码”
     */
    fun isFingerprintAvailable10(context: Context): Int {
        val manager: BiometricManager = BiometricManager.from(context)
        return manager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)
    }

    enum class Stage {
        UNSUPORTFINGER, NEED_CLOSE_SCREAM_FINGER, NEED_FINGER, UNKNOW_ERROR
    }



    /**
     *  6.0~9.0 以上判断方法返回值见上文的“是否可用的状态码”
     */
    @RequiresApi(Build.VERSION_CODES.M)
    fun isFingerprintAvailable6(context: Context): Stage {
        var keyguardManager = context.getSystemService(KeyguardManager::class.java)
        val fingerprintManager = context.getSystemService(FingerprintManager::class.java)
        return when {
            !fingerprintManager.isHardwareDetected -> {
                Stage.UNSUPORTFINGER
            }
            !keyguardManager.isKeyguardSecure -> {
                Stage.NEED_CLOSE_SCREAM_FINGER
            }
            !fingerprintManager.hasEnrolledFingerprints() -> {
                Stage.NEED_FINGER
            }
            else -> Stage.UNKNOW_ERROR
        }
    }

    /**
     * 开始验证
     *
     * @param activity
     * @param callBack 验证结果回调
     */
    open fun authenticate10(activity: FragmentActivity, callBack: BiometricPrompt.AuthenticationCallback) {
        val promptInfo: BiometricPrompt.PromptInfo =
            BiometricPrompt.PromptInfo.Builder().setTitle("验证指纹").setSubtitle("请在手机上,读取指纹")
                .setNegativeButtonText("采用其他方式").build()
        val prompt = BiometricPrompt(activity, ContextCompat.getMainExecutor(activity), callBack)
        prompt.authenticate(promptInfo)
    }

    /**
     * 开始验证
     *
     * @param activity
     * @param callBack 验证结果回调
     */
    @RequiresApi(Build.VERSION_CODES.M)
    open fun authenticate6(context: Context,mListener:CipherListener) {
        //Android KeyStore系统允许你存储加密密钥，keystore也分为多种。
        // 如果是”AndroidKeyStore”这种类型的话，keystore难以从设备中导出，
        // 并且可以指明key的使用规则，例如只有用户验证后，才可以使用key等
        var mKeyStore = KeyStore.getInstance("AndroidKeyStore")

        //根据一些指定的参数，例如算法，补码模式等参数，来生成一个新的key。
        var mKeyGenerator =
            KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")

        var defaultCipher = Cipher.getInstance(
            KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7
        )
        //现在增加安全性！前面已经提到如果将key存放在AndroidKeyStore中，
        // 可以为key设置一些保护(KeyProtection)，比如说用户验证过才可以使用key，那我们可以利用这点来增加安全性。
        createKey(mKeyStore, mKeyGenerator, true)

        //读取指纹信息
        if (creatCipher(mKeyStore, defaultCipher)) {
            mListener.backCipher(defaultCipher)
        }
    }

    //创建一对密钥,只有用户通过指纹认证后才能使用
    @RequiresApi(Build.VERSION_CODES.M)
    private fun createKey(mKeyStore: KeyStore, mKeyGenerator: KeyGenerator, invalidateKey: Boolean) {
        try {
            mKeyStore.load(null)
            var builder = KeyGenParameterSpec.Builder(DEFAULT_KEY_NAME, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT).setBlockModes(KeyProperties.BLOCK_MODE_CBC).setUserAuthenticationRequired(true)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                builder.setInvalidatedByBiometricEnrollment(invalidateKey)
            }

            mKeyGenerator.init(builder.build())
            mKeyGenerator.generateKey()

        } catch (e: Exception) {
            e.printStackTrace()
        }
    }


    //如果锁屏在秘钥生成后被禁用活重置,或者是秘钥生成后注册指纹
    private fun creatCipher(mKeyStore: KeyStore, cipher: Cipher): Boolean {
        try {
            mKeyStore.load(null)
            var key: SecretKey = mKeyStore.getKey(DEFAULT_KEY_NAME, null) as SecretKey
            cipher.init(Cipher.ENCRYPT_MODE, key)
            return true
        } catch (e: Exception) {
            e.printStackTrace()
        }
        ToastUtils.show("您还没有录制指纹")
        return false
    }

    interface CipherListener{
        fun backCipher(cipher: Cipher)
    }

}